package xman.mssh.spring.aop.annotation;

import java.lang.reflect.Method;

import javax.annotation.PostConstruct;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import xman.mssh.spring.SpringBeanDemo;

@Component
@Aspect
public class AnnotationAspectDemo {
    static Logger logger = LoggerFactory.getLogger(AnnotationAspectDemo.class);
    
    @PostConstruct
    public void init() {
        logger.info("+++++++Annonation Aspect init+++++");
    }
    
    /**
     * Wave Before Advice to JoinPoint through annotation PointCut
     */
    @Around("@annotation(xman.mssh.spring.aop.annotation.AnnotationPointCut)")
    public Object method(ProceedingJoinPoint pjp) throws Throwable {
        logger.info("++++++AnnotationPointCut start+++++");
        Object result = pjp.proceed();
        return result;
    }
    
    // @Around("execution (* xman.mssh.spring.SpringBeanDemo.*(..))")
    public Object aspect(ProceedingJoinPoint pjp) throws Throwable {
        // Object result = pjp.proceed();
        
        // 反射方式实现调用
        String methodName = pjp.getSignature().getName();
        Object[] params = pjp.getArgs();
        Class<?>[] paramClazzs = null;
        if (params != null && params.length > 0) {
            paramClazzs = new Class<?>[params.length];
            int i = 0;
            for (Object param : params) {
                paramClazzs[i++] = param.getClass();
            }
        }
        
        SpringBeanDemo target = (SpringBeanDemo) pjp.getTarget();
        Method method = target.getClass().getMethod(methodName, paramClazzs);
        logger.info(this.getClass().getName() + " # return type : " + method.getReturnType());
        Object result = target.getClass().getMethod(methodName, paramClazzs).invoke(target, params);
        return result;
    }
    
}
